package cn.e2win.biz.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import cn.e2win.base.entity.BaseEntity;
import cn.e2win.base.json.vo.Pager;
import cn.e2win.biz.dbo.DsEmp;
import cn.e2win.biz.security.UserSession;
import cn.e2win.biz.util.DataAccessException;
import cn.e2win.biz.util.StringUtils;


@Repository
public class BaseDAOHibernateImpl extends
		HibernateDaoSupport implements BaseDAO {

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	@Resource  
    public void setSessionFacotry(SessionFactory sessionFacotry) {  
        super.setSessionFactory(sessionFacotry);  
    }
	
	@Autowired
	private SimpleJdbcTemplate simpleJdbcTemplate;



	public List<Object> read(final Class clazz, final Serializable[] ids) {
		try {
			return (List<Object>) getHibernateTemplate().execute(
					new HibernateCallback() {
						public Object doInHibernate(Session session)
							throws SQLException {
							return session.createCriteria(clazz.getName())
									.add(Restrictions.in("id", ids)).list();
						}
					});
		} catch (Exception e) {
			throw new DataAccessException(e);
		}

	}

	public List<Object> readAll(Class clazz) {
		try {
			return (List<Object>) getHibernateTemplate().find("from " + clazz.getName() +" cls where cls.activeStatusInt is null or cls.activeStatusInt<>0");
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	public Object getEntity(String hql) {
		try {
			List list = getHibernateTemplate().find(hql);
			if(list!=null && list.size()>0){
				return list.get(0);
			}else{
				return null;
			}
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	public List getObjectListByHql(String hql) {
		try {
			return getHibernateTemplate().find(hql);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	@Override
	public void saveAll(List<?>  list) {
		try {
			getHibernateTemplate().saveOrUpdateAll(list);
		} catch (Exception e) {
			e.printStackTrace();
			throw new DataAccessException(e);
		}

	}
	@Override
	public Object save(Object  object) {
		try {
			return getHibernateTemplate().save(object);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}

	}

	@Override
	public void update(Object  object) {
		try {
			getHibernateTemplate().update(object);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}

	}


	public void delete(Class clazz, Serializable id) {
		try {
			delete(getEntity(clazz, id));
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}


	public void delete(Class clazz,Serializable[] ids) {
		try {
			delete(read(clazz, ids));
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}
	@Override
	public void delete(Object o) {
		try {
			getHibernateTemplate().delete(o);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	public void delete(Collection<Object> persistentObjects) {
		try {
			getHibernateTemplate().deleteAll(persistentObjects);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}



	@Override
	public List<Map<String, Object>> getListBySql(String sql, Map<String, ?> map) {
		try {
			if(map == null){
				map =new HashMap();
			}
			
			return simpleJdbcTemplate.queryForList(sql, map);
		} catch (Exception e) {
			e.printStackTrace();
			throw new DataAccessException(e);
		}

	}

	
	@Override
	public Map<String, Object> get1stRecordBySql(String sql, Map<String, ?> paramMap) {
		try {
			
			Map<String, Object> map = new HashMap<String, Object>();
			if(!StringUtils.isEmpty(sql)){
				QueryHelper queryHelper = new QueryHelper(sql, paramMap);
				List<Map<String, Object>> list =  simpleJdbcTemplate.queryForList(queryHelper.getSql(),queryHelper.getDbMap());
	
				if(list!=null && list.size()>0){
					map = list.get(0);
				}
			}
			return map;
		} catch (Exception e) {
			throw new DataAccessException(e);
		}

	}
	/**
	 * Builder condition sentence.
	 * 
	 * @param alias
	 *            entity class alias
	 * @param hsql
	 *            hql sentence
	 * @param key
	 *            entity attribute
	 * @param operation
	 *            some operation
	 * @param valueName
	 *            value
	 */
	protected void buildCondition(String alias, StringBuffer hsql, String key,
			String operation, String valueName) {
		if (null == key || null == hsql || alias == null) {
			throw new RuntimeException("build hql error");
		}
		if (null == valueName) {
			valueName = key;
		}
		if (operation == null) {
			operation = "=";
		}
		hsql.append(" and ").append(alias).append(".").append(key).append(" ")
				.append(operation).append(" :").append(valueName);
	}
	



	@Override
	public void processPager(Pager pager)throws SQLException{		
		System.err.println(pager.getSql());
		logger.info("logger.info================="+pager.getSql());
		
		if(pager.isReturnAll()){//无需分页
			pager.setResultList(simpleJdbcTemplate.queryForList(pager.getSql(), pager.getDbMap()));
		}else{
			int totalCount = simpleJdbcTemplate.queryForInt(getCountSQL(pager.getSql()), pager.getDbMap());
			pager.setTotalCount(totalCount);
			if(totalCount>0){
				int totalPage = totalCount/pager.getNumPerPage();
				if(totalCount > totalPage * pager.getNumPerPage()){
					totalPage = totalPage + 1;
				}
				pager.setTotalPage(totalPage);
				if(pager.getPageNum()>totalPage){
					pager.setPageNum(totalPage);
				}		
				pager.setResultList(simpleJdbcTemplate.queryForList(getPageSQL(pager.getSql(),pager.getPageNum(),pager.getNumPerPage()), pager.getDbMap()));
			}else{
				pager.setTotalPage(0);
			}
		}
	}
	
	private String getPageSQL(String sql, int pageNum, int numPerPage){
		String returnSql = sql + " LIMIT " + (pageNum-1)*numPerPage + " , " + numPerPage;
		return returnSql;
	}
	private String getCountSQL(String sql){
		String returnSql = "SELECT COUNT(1) FROM (" + sql + ") AS COUNT_TABLE";
		return returnSql;
	}
	
	@Override
	public int updateBySql(String sql, Map<String, Object> args){
		return simpleJdbcTemplate.update(sql, args);
	}
	@Override
	public String getSeq(String formType, Integer coId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("formType", formType);
		paramMap.put("coId", coId);
		updateBySql("UPDATE sys_seq SET currentSeq = currentSeq+1 WHERE formType=:formType AND coId=:coId", paramMap);
		Map<String,Object> map = get1stRecordBySql("SELECT prfix, currentSeq FROM sys_seq WHERE formType=:formType AND coId=:coId", paramMap);
		
		return map.get("prfix") + map.get("currentSeq").toString();
		
	}

	@Override
	public Object getEntity(Class clazz, Serializable id) {
		try {
			return getHibernateTemplate().get(clazz.getName(), id);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	@Override
	public Map<String, Object> getEntity(BaseEntity entity) {
		//TODO
		return null;
	}
	
	@Override
	public Object merge(Object o) {
		try {
			return getHibernateTemplate().merge(o);
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}

	@Override
	public List<Map<String, Object>> getListBySqlAutoParam(String sql, Map<String, ?> map) {
		try {

			QueryHelper queryHelper = new QueryHelper(sql, map);
			return simpleJdbcTemplate.queryForList(queryHelper.getSql(), queryHelper.getDbMap());
		} catch (Exception e) {
			throw new DataAccessException(e);
		}
	}
	/*
	private String getOperator (String field,Map<String, Object> dbMap){
		String key = field;
		String oper = " = :";
		if(field.endsWith(_I)){
			return "";
		}else if(field.indexOf(_L)>0){
			key = field.substring(0, field.length() - _L.length());
			oper = " LIKE :";
			dbMap.put(field, "%" + dbMap.get(field) + "%");
		}else if(field.endsWith(_B)){
			key = field.substring(0, field.length() - _B.length());
			oper = " >= :";
			if(field.endsWith("Date" + _B)){
				dbMap.put(field, DateUtils.str2Date((String)dbMap.get(field)));
			}else if(field.endsWith("id" + _B) || field.endsWith("Id" + _B) || field.endsWith("Int" + _B)){
				dbMap.put(field, Integer.parseInt((String)dbMap.get(field)));				
			}else if(field.endsWith("Float" + _B)){
				dbMap.put(field, Float.parseFloat((String)dbMap.get(field)));				
			}		
		}else if(field.endsWith(_E)){
			key = field.substring(0, field.length() - _E.length());
			oper = " <= :";
			if(field.endsWith("Date" + _E)){
				dbMap.put(field, DateUtils.getOffsetDay(DateUtils.str2Date((String)dbMap.get(field)), 1));
			}else if(field.endsWith("id" + _E) || field.endsWith("Id" + _E) || field.endsWith("Int" + _E)){
				dbMap.put(field, Integer.parseInt((String)dbMap.get(field)));				
			}else if(field.endsWith("Float" + _E)){
				dbMap.put(field, Float.parseFloat((String)dbMap.get(field)));				
			}	
		}else if(field.endsWith(_N)){
			key = field.substring(0, field.length() - _N.length());
			oper = " <> :";
		}
		return " AND " + key + oper + field;
	}
	*/

}
